home *** CD-ROM | disk | FTP | other *** search
- #ifndef __ASK_MANAGER_H_
- #define __ASK_MANAGER_H_
-
- #include "pxtable.h"
- #include "khpxeerr.h"
- #include "strtable.h"
- #include "khquerry.h"
-
- extern int indexNo; // The only reason - error in PX Engine.
-
- /* AskManager works with list of querries and corresponding list of
- tables. Table names in list may be not unique.
-
- The manager works in the following manner:
- ( ATTENTION !!! NO OPTIMIZATION REFLECTED - IT IS EXPLANATION ONLY )
- a. Verification.
- EXAMPLES. Second table MUST contain common variable(s)
- with 1-st, third - with the 1-st or 2-nd and so on. If this
- condition fails, querry fails too, because one of tables is not
- linked with others.
- CHECKERS. At least one checked field should be present.
-
- b. Maketing.
- ANSWER table is created as combination of all checked
- fields in all tables. If there are the same field names,
- their names are modified: NAME, NAME_1 and so on.
-
- c. If there are only one table in querry.
- For every record call in cycle Find() function, copying results
- to ANSWER.
-
-
- After processing of this querry we get the table of EXAMPLE values
- and checked fields values. In the general case number of
- records in this table is less than in 1-st table (if CONDITIONs
- are not always TRUE).
-
- d. Second pass.
- We need only the data from second table which EXAMPLE field
- contains the same value as in 1-st table. In general, we should
- for EVERY record in WORK table
- for EVERY record in 2-nd table
- test if(EXAMPLE field (1) == EXAMPLE field (2) )
-
- Really, having 1.000 records (WORK) and 1.000 records (2), we
- need 1.000.000 passes through 2-nd table !!!
-
- The solution is: test more than one line of WORK in every pass, or
- (the same result) to allocate the largest possible buffer for
- keepeng 2-nd table in memory.
-
- AskManager builds the table, containing checked fields for
- examples (adding if necessary new example names from 2-nd table),
- checked fields for fields, containing CONDITIONS (we assume Address
- is the 2-nd table field with CONDITION):
-
- Name: Address:
- _________________________________________________
- EXAMPLE, CHECKPLUS EXAMPLE, CHECKPLUS
-
- and fill it with field numbers of 1-st and 2-nd tables, for
- which EXAMPLE values are the same.
-
- The real algorythm is:
-
- Get 1-st record from 2-nd table. Check condition (if present),
- if failed, get next record (using Find() and values of examples).
- If condition is TRUE, for all fields in WORK table (for which
- the largest buffer is allocated) find the record with the same
- example(s) values, as in the record from 2-nd table.
- Attention!!! We have already check conditions in WORK table.
- Now we have two records, from 1-st table and 2-nd table, with
- common EXAMPLE values. For all checked but not containing
- EXAMPLES fields with the same names (if no such fields - no
- checking) test, if their values are the same.
- Fill the ANSWER table. If the table was not last in querry -
- rename it to WORK.
-
- Repeate operation for all tables in querry.
- */
- /* ATTENTION !!! We don't check, if BLOB fields contains conditions
- or checkers. Do it !!!
- */
- class KH_AskManager
- {
- protected:
- KH_PXTable** tables; // List of tables
- KH_QUERRY** querryList; // There are 1-to-1 correspondence
- // between tables and querries
- KH_PXTable* workTable; // We use this table as temporary
- // to keep sub-results
- KH_PXTable* answerTable; // Resulting table
- int numberOfTables; // Total number of tables in "Ask"
-
- public:
- // Constructor. Arguments: names of tables, querries, number of tables
- KH_AskManager(char** tableNames, KH_QUERRY** querries, int num);
-
- /* Destructor. Closes tables with KH_SHARE flag == 1, reduces this flag
- for other tables. Removes WORK and WORK1 tables.
- */
- ~KH_AskManager();
- /* Service (non-user) function. Creates ANSWER.DB table containing all
- checked fields from all querries. Return value: 0 (fail), 1 (success).
- The enumeration KH_CHECKERS could include CALC (not in 1.0).
- This option is used to produce new field with the same type as in
- source field, and value which is calculated: x, CALC 3 * x.
- In this string we define EXAMPLE variable x, and forse the AskManager
- to create new column. x have the value of current field, and field
- value in new column will be 3 * x. createTable() considers CALC
- as CHECK and include new column to ANSWER.
- */
- int createAnswerTable(int nOT);
- /* checkQuerry() tests the querry BEFORE processing. It may be virtual,
- because user could redefine the verification procedure.
- */
- /*virtual*/ int KH_AskManager::checkQuerry();
- KH_STRTABLE* getExamples(int n);
- KH_STRTABLE* getCurrExamples(int n);
-
- KH_STRTABLE* makeQuerry(int n); // Produce complete querry from packed one
- int processSingleTable(); // If there are 1 table in querry
- int processMultipleTables();
- int process(); // Process the querry
- int moveToRec(int* ex, int cur, int n, int m, FIELDHANDLE cSIHandle);
- int getExSrc(KH_STRTABLE* ex, KH_STRTABLE* cur, int* eNums,
- FIELDHANDLE* exFlds);
-
- int getExFields(FIELDHANDLE* exFlds, int i);
- void writeField(KH_PXTable* srcTable, KH_PXTable* destTable);
- void dumpAnswer();
-
- };
-
- #endif __ASK_MANAGER_H_
-
-